package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.common.Result;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.service.*;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dish")
@Slf4j
@Api("菜品管理")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealService setmealService;


    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private RedisTemplate redisTemplate;


    //新增菜品
    @PostMapping
    public Result saveWithFlavor(@RequestBody DishDto dishDto) {
        dishService.saveWithFlavor(dishDto);

        //删除redis中所有菜品数据的缓存
        Set set = redisTemplate.keys("dish_*");
        redisTemplate.delete(set);
        return Result.success("保存成功");
    }

    //菜品管理分页查询
    @GetMapping("/page")
    public Result<Page> page(int page, int pageSize, String name) {
        //构造分页查询的条件
        Page<Dish> dishPage = new Page<>(page, pageSize);

        LambdaQueryWrapper<Dish> dishWrapper = new LambdaQueryWrapper<>();
        dishWrapper.like(name != null, Dish::getName, name);
        dishWrapper.orderByDesc(Dish::getUpdateTime);

        dishService.page(dishPage, dishWrapper);

        //封装数据-total
        Page<DishDto> dtoPage = new Page<>();
        long total = dishPage.getTotal();
        dtoPage.setTotal(total);

        //封装数据-records
        List<Dish> records = dishPage.getRecords();
        List<DishDto> dtoList = records.stream().map(dish ->
                {
                    DishDto dishDto = new DishDto();
                    //把dish里面的records复制到DishDto中
                    BeanUtils.copyProperties(dish, dishDto);
                    //根据id查询分类的对象
                    Category category = categoryService.getById(dish.getCategoryId());
                    if (category != null) {
                        dishDto.setCategoryName(category.getName());
                    }
                    return dishDto;
                }
        ).collect(Collectors.toList());
        Page<DishDto> dishDtoPage = dtoPage.setRecords(dtoList);
        return Result.success(dishDtoPage);

    }

    //修改时数据回显
    @GetMapping("/{id}")
    public Result<DishDto> getByIdWithFlavor(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return Result.success(dishDto);
    }

    @PutMapping
    public Result update(@RequestBody DishDto dishDto){
        dishService.updateWithFlavor(dishDto);

        //删除redis中所有菜品的缓存
        Set set = redisTemplate.keys("dish_*");
        redisTemplate.delete(set);
        return Result.success("修改成功");
    }



    /**
     * 回显添加套餐时的菜品信息
     *
     * 封装到dishdto中,并且还要赋值categoryname,还要查询菜品所对应的口味信息
     * @param dish
     * @return
     */
    @GetMapping("/list")
    public Result<List<DishDto>> list(Dish dish){
        //先查询Redis,如果Redis有数据,就直接返回
        String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();

        List<DishDto> dtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);


        if (! CollectionUtils.isEmpty(dtoList)) {
            log.info("redis中有缓存数据,直接查询redis,无需查询数据库");
            return Result.success(dtoList);
        }

        //根据条件查询套餐下的菜品信息  category_id  菜品为起售状态的 status = 1 ,根据更新时间倒序排序
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId() != null,Dish::getCategoryId, dish.getCategoryId());
        wrapper.eq(Dish::getStatus, 1);
        //添加排序条件
        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(wrapper);


        List<DishDto> dishDtoList = list.stream().map(dish1 ->
                {
                    DishDto dishDto = new DishDto();
                    BeanUtils.copyProperties(dish1, dishDto);

                    Long categoryId = dish1.getCategoryId();
                    //根据id查询对应的category,然后给dishDto中的categoryname赋值
                    Category category = categoryService.getById(categoryId);

                    if (category != null) {
                        String name = category.getName();

                        //为dishDto中的categorName赋值
                        dishDto.setCategoryName(name);
                    }

                    //还要为当前的菜品下的口味赋值
                    Long dish1Id = dish1.getId();
                    LambdaQueryWrapper<DishFlavor> dishDtoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    dishDtoLambdaQueryWrapper.eq(DishFlavor::getDishId, dish1Id);
                    List<DishFlavor> dishFlavorList = dishFlavorService.list(dishDtoLambdaQueryWrapper);
                    dishDto.setFlavors(dishFlavorList);

                    return dishDto;
                }
        ).collect(Collectors.toList());

        //Redis中没有数据,把查询数据库中的数据缓存到Redis中
        redisTemplate.opsForValue().set(key, dishDtoList, 24, TimeUnit.HOURS);

        return Result.success(dishDtoList);


    }


    @DeleteMapping
    public Result remove(@RequestParam List ids) {

        /*LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.in(SetmealDish::getDishId, ids);
        List<SetmealDish> dishList = setmealDishService.list(setmealDishWrapper);

        if (! CollectionUtils.isEmpty(dishList)){

            throw new CustomException("菜品关联了套餐,不能直接删除");
        }*/


        dishService.removes(ids);
        //删除redis中菜品的缓存数据
        Set set = redisTemplate.keys("dish_*");
        redisTemplate.delete(set);
        return Result.success("删除成功");
    }


    /**
     * 批量停售,起售
     * 利用id进行修改,然后把菜品里面的状态修改为0
     * 如果想要先停售菜品需要先停售套餐
     *
     * 先判断套餐是否是停售的,如果是停售的就可以直接停售菜品,如果套餐时起售的就不能够停售菜品,就会抛异常
     * update dish set status = 0 where id in(1464201727610753025,?);
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public Result haltSales(@RequestParam List<Long> ids,@PathVariable Integer status) {

        // 如果停售的菜品关联了在售的套餐,是不允许的,需要像前端提示错误信息
        if (status == 0) {
            LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
            setmealDishWrapper.in(SetmealDish::getDishId, ids);
            List<SetmealDish> dishList = setmealDishService.list(setmealDishWrapper);

            if (! CollectionUtils.isEmpty(dishList)){
                List<Long> setmealIdList = dishList.stream().map(setmealDish -> {
                    Long setmealId = setmealDish.getSetmealId();
                    return setmealId;
                }).collect(Collectors.toList());

                LambdaQueryWrapper<Setmeal> setmealWrapper = new LambdaQueryWrapper<>();
                setmealWrapper.in(Setmeal::getId, setmealIdList);
                setmealWrapper.eq(Setmeal::getStatus, 1);
                int count = setmealService.count(setmealWrapper);

                if (count > 0){
                    throw new CustomException("该套餐下关联有套餐,不能停售");
                }
            }
        }

    /*    //批量修改套餐的状态
        List<Dish> dishes = dishService.listByIds(ids);
        dishes.stream().forEach(dish -> {
            dish.setStatus(status);
        });

        dishService.updateBatchById(dishes);

        return Result.success();*/


        UpdateWrapper<Dish> wrapper = new UpdateWrapper();
        wrapper.in("id", ids);
        wrapper.set("status",status);

        dishService.update(wrapper);
        return Result.success();
    }



}
